module alu_mod(
	rst,

	//杈撳叆閮ㄥ垎
	alu_en_i,
	alu_reg_addr_i,
	alu_csr_addr_i,
	alu_where_i,
	alu_how_i,
	alu_data_i,
	alu_data1_i,
	alu_mcause_i,
	alu_mtval_i,

	//鍐呭瓨澶勭悊鎺ュ彛
	mem_data_i,
	mem_en_o,
	mem_rw_o,
	mem_addr_o,
	mem_data_o,
	mem_byte_en_o,

	//瀵勫瓨鍣ㄥ鐞嗘帴鍙
	reg_en_o,
	reg_addr_o,
	reg_data_o,

	//csr鐘舵€佸瘎瀛樺櫒澶勭悊鎺ュ彛
	csr_en_o,
	csr_addr_o,
	csr_data_o,

	//涓柇瀹炵幇鎺ュ彛
	csr_int_en_o,
	csr_mepc_o,
	csr_mcause_o,
	csr_mtval_o,
	csr_mstatus_o
);

input rst;

//杈撳叆閮ㄥ垎
input alu_en_i;
input [4:0] alu_reg_addr_i;
input [11:0] alu_csr_addr_i;
input [1:0] alu_where_i;
input [7:0] alu_how_i;
input signed [31:0] alu_data_i;
input signed [31:0] alu_data1_i;
input [31:0] alu_mcause_i;
input [31:0] alu_mtval_i;

//鍐呭瓨澶勭悊鎺ュ彛
input [31:0] mem_data_i;
output reg mem_en_o;
output reg mem_rw_o;
output reg [31:0] mem_addr_o;
output reg [31:0] mem_data_o;
output reg [3:0] mem_byte_en_o;

//瀵勫瓨鍣ㄥ鐞嗘帴鍙
output reg reg_en_o;
output reg [4:0] reg_addr_o;
output reg [31:0] reg_data_o;

//csr鐘舵€佸瘎瀛樺櫒澶勭悊鎺ュ彛
output reg csr_en_o;
output reg [11:0] csr_addr_o;
output reg [31:0] csr_data_o;

//涓柇瀹炵幇鎺ュ彛
output reg csr_int_en_o;
output reg [31:0] csr_mepc_o;
output reg [31:0] csr_mcause_o;
output reg [31:0] csr_mtval_o;
output reg [31:0] csr_mstatus_o;

always @ ( * ) begin
	if( rst == 1'b1) begin
		mem_en_o <= 1'b0;
		mem_rw_o <= 1'b0;
		mem_addr_o <= 32'h0;
		mem_data_o <= 32'h0;
		mem_byte_en_o <= 4'h0;
		reg_en_o <= 1'b0;
		reg_addr_o <= 5'h0;
		reg_data_o <= 32'h0;
		csr_en_o <= 1'b0;
		csr_addr_o <= 12'h0;
		csr_data_o <= 32'h0;
		csr_int_en_o <= 1'b0;
		csr_mepc_o <= 32'h0;
		csr_mcause_o <= 32'h0;
		csr_mtval_o <= 32'h0;
		csr_mstatus_o <= 32'h0;
	end else if (alu_en_i == 1'b1) begin

	if ( alu_where_i == 2'h0) begin
		if ( alu_how_i == 8'h0) begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= alu_data_i + alu_data1_i;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h1) begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= alu_data_i - alu_data1_i;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h2) begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= alu_data_i & alu_data1_i;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h3) begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= alu_data_i | alu_data1_i;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h4) begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= alu_data_i ^ alu_data1_i;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h5) begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= alu_data_i << alu_data1_i;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h6) begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= alu_data_i >> alu_data1_i;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h7) begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= alu_data_i >>> alu_data1_i;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h8) begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= {31'b0,(alu_data_i < alu_data1_i)};
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h0) begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= {31'b0,($unsigned(alu_data_i) < $unsigned(alu_data1_i))};
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h10) begin
			mem_en_o <= 1'b1;
			mem_rw_o <= 1'b0;
			mem_addr_o <= alu_data_i + alu_data1_i;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h1;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= {{24{mem_data_i[7]}},mem_data_i[7:0]};
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h20) begin
			mem_en_o <= 1'b1;
			mem_rw_o <= 1'b0;
			mem_addr_o <= alu_data_i + alu_data1_i;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h3;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= {{16{mem_data_i[15]}},mem_data_i[15:0]};
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h30) begin
			mem_en_o <= 1'b1;
			mem_rw_o <= 1'b0;
			mem_addr_o <= alu_data_i + alu_data1_i;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'hf;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= mem_data_i;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h40) begin
			mem_en_o <= 1'b1;
			mem_rw_o <= 1'b0;
			mem_addr_o <= alu_data_i + alu_data1_i;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h1;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= {24'b0,mem_data_i[7:0]};
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h50) begin
			mem_en_o <= 1'b1;
			mem_rw_o <= 1'b0;
			mem_addr_o <= alu_data_i + alu_data1_i;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h3;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= {16'b0,mem_data_i[15:0]};
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b0;
			reg_addr_o <= 5'h0;
			reg_data_o <= 32'h0;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end
	end else if ( alu_where_i == 2'h1) begin
		if( alu_how_i == 8'h60) begin
			mem_en_o <= 1'b1;
			mem_rw_o <= 1'b1;
			mem_addr_o <= alu_data_i + alu_data1_i;
			mem_data_o <= alu_mcause_i;
			mem_byte_en_o <= 4'h1;
			reg_en_o <= 1'b0;
			reg_addr_o <= 5'h0;
			reg_data_o <= 32'h0;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h70 ) begin
			mem_en_o <= 1'b1;
			mem_rw_o <= 1'b1;
			mem_addr_o <= alu_data_i + alu_data1_i;
			mem_data_o <= alu_mcause_i;
			mem_byte_en_o <= 4'h3;
			reg_en_o <= 1'b0;
			reg_addr_o <= 5'h0;
			reg_data_o <= 32'h0;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h80 ) begin
			mem_en_o <= 1'b1;
			mem_rw_o <= 1'b1;
			mem_addr_o <= alu_data_i + alu_data1_i;
			mem_data_o <= alu_mcause_i;
			mem_byte_en_o <= 4'hf;
			reg_en_o <= 1'b0;
			reg_addr_o <= 5'h0;
			reg_data_o <= 32'h0;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b0;
			reg_addr_o <= 5'h0;
			reg_data_o <= 32'h0;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end
	end else if ( alu_where_i == 2'h2) begin
		if( alu_how_i == 8'h0 ) begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= alu_data1_i;
			csr_en_o <= 1'b1;
			csr_addr_o <= alu_csr_addr_i;
			csr_data_o <= alu_data_i;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end else if ( alu_how_i == 8'h3 ) begin
			if( alu_how_i == 8'h0) begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= alu_data1_i;
			csr_en_o <= 1'b1;
			csr_addr_o <= alu_csr_addr_i;
			csr_data_o <= alu_data1_i | alu_data_i;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
			end
		end else if ( alu_how_i == 8'h2 ) begin
			if( alu_how_i == 8'h0) begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b1;
			reg_addr_o <= alu_reg_addr_i;
			reg_data_o <= alu_data1_i;
			csr_en_o <= 1'b1;
			csr_addr_o <= alu_csr_addr_i;
			csr_data_o <= alu_data1_i & (~alu_data_i);
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
			end
		end else begin
			mem_en_o <= 1'b0;
			mem_rw_o <= 1'b0;
			mem_addr_o <= 32'h0;
			mem_data_o <= 32'h0;
			mem_byte_en_o <= 4'h0;
			reg_en_o <= 1'b0;
			reg_addr_o <= 5'h0;
			reg_data_o <= 32'h0;
			csr_en_o <= 1'b0;
			csr_addr_o <= 12'h0;
			csr_data_o <= 32'h0;
			csr_int_en_o <= 1'b0;
			csr_mepc_o <= 32'h0;
			csr_mcause_o <= 32'h0;
			csr_mtval_o <= 32'h0;
			csr_mstatus_o <= 32'h0;
		end
	end else if ( alu_where_i == 2'h3) begin
		mem_en_o <= 1'b0;
		mem_rw_o <= 1'b0;
		mem_addr_o <= 32'h0;
		mem_data_o <= 32'h0;
		mem_byte_en_o <= 4'h0;
		reg_en_o <= 1'b0;
		reg_addr_o <= 5'h0;
		reg_data_o <= 32'h0;
		csr_en_o <= 1'b0;
		csr_addr_o <= 12'h0;
		csr_data_o <= 32'h0;
		csr_int_en_o <= 1'b1;
		csr_mepc_o <= alu_data1_i;
		csr_mcause_o <= alu_mcause_i;
		csr_mtval_o <= alu_mtval_i;
		csr_mstatus_o <= (alu_data_i & (~32'h8)) | ((alu_data_i & 32'h8) << 4);
	end else begin
		mem_en_o <= 1'b0;
		mem_rw_o <= 1'b0;
		mem_addr_o <= 32'h0;
		mem_data_o <= 32'h0;
		mem_byte_en_o <= 4'h0;
		reg_en_o <= 1'b0;
		reg_addr_o <= 5'h0;
		reg_data_o <= 32'h0;
		csr_en_o <= 1'b0;
		csr_addr_o <= 12'h0;
		csr_data_o <= 32'h0;
		csr_int_en_o <= 1'b0;
		csr_mepc_o <= 32'h0;
		csr_mcause_o <= 32'h0;
		csr_mtval_o <= 32'h0;
		csr_mstatus_o <= 32'h0;
	end
			
	end else begin
		mem_en_o <= 1'b0;
		mem_rw_o <= 1'b0;
		mem_addr_o <= 32'h0;
		mem_data_o <= 32'h0;
		mem_byte_en_o <= 4'h0;
		reg_en_o <= 1'b0;
		reg_addr_o <= 5'h0;
		reg_data_o <= 32'h0;
		csr_en_o <= 1'b0;
		csr_addr_o <= 12'h0;
		csr_data_o <= 32'h0;
		csr_int_en_o <= 1'b0;
		csr_mepc_o <= 32'h0;
		csr_mcause_o <= 32'h0;
		csr_mtval_o <= 32'h0;
		csr_mstatus_o <= 32'h0;
	end

end

endmodule
